package com.example.baselibrary.ioc;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.view.View;
import android.widget.Toast;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author 吴子玄
 */
public class ViewUtils {
    public static void inject(Activity activity){
        inject(new ViewFinder(activity),activity);
    }
    public static void inject(View view){
        inject(new ViewFinder(view),view);
    }
    public static void inject(Activity activity,Object object){
        inject(new ViewFinder(activity),object);
    }
    public static void inject(View view, Object object){
        inject(new ViewFinder(view),object);
    }
    public static void inject(ViewFinder viewFinder, Object object){
        injectField(viewFinder,object);
        injectEvent(viewFinder,object);
    }

    private static void injectField(ViewFinder finder, Object object) {
        // 1. 获取类里面所有的属性
        Class<?> clazz = object.getClass();
        // 获取所有属性包括私有和共有
        Field[] fields = clazz.getDeclaredFields();

        // 2. 获取ViewById的里面的value值
        for (Field field : fields) {
            ViewById viewById = field.getAnnotation(ViewById.class);
            if (viewById != null) {
                // 获取注解里面的id值  --> R.id.test_tv
                int viewId = viewById.value();
                // 3. findViewById 找到View
                View view = finder.findViewById(viewId);
                if (view != null) {
                    // 能够注入所有修饰符  private public
                    field.setAccessible(true);
                    // 4. 动态的注入找到的View
                    try {
                        field.set(object, view);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    private static void injectEvent(ViewFinder finder, Object object) {
        // 1. 获取类里面所有的方法
        Class<?> clazz = object.getClass();
        Method[] methods = clazz.getDeclaredMethods();

        // 2. 获取Onclick的里面的value值
        for (Method method : methods) {
            OnClick onClick = method.getAnnotation(OnClick.class);
            if (onClick != null) {
                int[] viewIds = onClick.value();
                for (int viewId : viewIds) {
                    // 3. findViewById 找到View
                    View view = finder.findViewById(viewId);


                    // 扩展功能 检测网络
                    boolean isCheckNet = method.getAnnotation(CHeckNet.class) != null;

                    if (view != null) {
                        // 4. view.setOnClickListener
                        view.setOnClickListener(new DeclearOnClickListener(object,method, isCheckNet));
                    }
                }
            }
        }
    }
    public static class DeclearOnClickListener implements View.OnClickListener{
        private Object object;
        private Method method;
        private boolean isCheckNet;

        public DeclearOnClickListener(Object object, Method method, boolean isCheckNet) {
            this.object = object;
            this.method = method;
            this.isCheckNet = isCheckNet;
        }

        @Override
        public void onClick(View v) {
            if (isCheckNet && !netWorkAvaliable(v.getContext())){
                Toast.makeText(v.getContext(), "亲，您的网络不太给力", Toast.LENGTH_LONG).show();
                return;
            }

            method.setAccessible(true);
            try {
                method.invoke(object,v);
            } catch (Exception e) {
                e.printStackTrace();
                Object[] objects = new Object[]{};
                try {
                    method.invoke(object,objects);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }


    }






    private static boolean netWorkAvaliable(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()){
            return true;
        }else {
            return false;
        }
    }
}
